package com.opennews.openplatform.controller;

import com.opennews.openplatform.dto.income.expense.detail.CreateIncomeExpenseDetailDto;
import com.opennews.openplatform.dto.income.expense.detail.IncomeExpenseDetailQueryArgument;
import com.opennews.openplatform.dto.income.expense.detail.UpdateIncomeExpenseDetailDto;
import com.opennews.openplatform.myspringbootcore.dto.ApiResponse;
import com.opennews.openplatform.myspringbootcore.dto.IdentityDto;
import com.opennews.openplatform.myspringbootcore.security.MyClaims;
import com.opennews.openplatform.myspringbootcore.util.DateHelper;
import com.opennews.openplatform.myspringbootcore.util.SharedUtil;
import com.opennews.openplatform.myspringbootmvccore.helper.HttpResponseHelper;
import com.opennews.openplatform.myspringbootmvccore.security.RequestIdentityExtractor;
import com.opennews.openplatform.service.IncomeExpenseDetailService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@RequiredArgsConstructor
@RestController
@RequestMapping("/income-expense-detail")
public class IncomeExpenseDetailController {
    private final IncomeExpenseDetailService incomeExpenseDetailService;
    private final RequestIdentityExtractor requestIdentityExtractor;
    private final HttpResponseHelper httpResponseHelper;

    @GetMapping("/query-list-with-summary-by-account-group")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> queryListWithSummaryByAccountGroup(@RequestParam int pageSize, @RequestParam int pageIndex) {
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;
        List<Map<String, Object>> result = incomeExpenseDetailService.queryListWithSummaryByAccountGroup(accountGroupId, pageSize, pageIndex);

        return httpResponseHelper.getSuccessResponse(result);
    }

    @GetMapping("/query-list-by-account-group")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> queryListByAccountGroup(
            @RequestParam String startDate,
            @RequestParam String endDate,
            @RequestParam String keyword,
            @RequestParam String keywordsSearchCondition,
            @RequestParam String type,
            @RequestParam String detailType,
            @RequestParam String paymentType,
            @RequestParam String bankCardId,
            @RequestParam int pageSize,
            @RequestParam int pageIndex) {
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;

        // Prepares the query argument.
        IncomeExpenseDetailQueryArgument queryArgument = new IncomeExpenseDetailQueryArgument();
        queryArgument.startDate = SharedUtil.isNullOrEmpty(startDate) ? null : DateHelper.parseFromLongDateTime(startDate);
        queryArgument.endDate = SharedUtil.isNullOrEmpty(endDate) ? null : DateHelper.parseFromLongDateTime(endDate);
        queryArgument.keyword = keyword;
        queryArgument.keywordsSearchCondition = keywordsSearchCondition;
        queryArgument.type = type;
        queryArgument.detailType = detailType;
        queryArgument.paymentType = paymentType;
        queryArgument.bankCardId = bankCardId;
        queryArgument.accountGroupId = accountGroupId;
        queryArgument.pageSize = pageSize;
        queryArgument.pageIndex = pageIndex;

        List<Map<String, Object>> result = incomeExpenseDetailService.queryListByAccountGroup(queryArgument);

        return httpResponseHelper.getSuccessResponse(result);
    }

    @GetMapping("/query-total-amount-by-account-group")
    public ResponseEntity<ApiResponse<BigDecimal>> queryTotalAmountByAccountGroup(
            @RequestParam String startDate,
            @RequestParam String endDate,
            @RequestParam String keyword,
            @RequestParam String keywordsSearchCondition,
            @RequestParam String type,
            @RequestParam String detailType,
            @RequestParam String paymentType,
            @RequestParam String bankCardId) {
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;

        // Prepares the query argument.
        IncomeExpenseDetailQueryArgument queryArgument = new IncomeExpenseDetailQueryArgument();
        queryArgument.startDate = SharedUtil.isNullOrEmpty(startDate) ? null : DateHelper.parseFromLongDateTime(startDate);
        queryArgument.endDate = SharedUtil.isNullOrEmpty(endDate) ? null : DateHelper.parseFromLongDateTime(endDate);
        queryArgument.keyword = keyword;
        queryArgument.keywordsSearchCondition = keywordsSearchCondition;
        queryArgument.type = type;
        queryArgument.detailType = detailType;
        queryArgument.paymentType = paymentType;
        queryArgument.bankCardId = bankCardId;
        queryArgument.accountGroupId = accountGroupId;

        BigDecimal result = incomeExpenseDetailService.queryTotalAmountByAccountGroup(queryArgument);

        return httpResponseHelper.getSuccessResponse(result);
    }

    @GetMapping("/query-details")
    public ResponseEntity<ApiResponse<Map<String, Object>>> queryDetails(@RequestParam String id) {
        Map<String, Object> result = incomeExpenseDetailService.queryDetails(requestIdentityExtractor.getClaims().accountGroupId, id);

        return httpResponseHelper.getSuccessResponse(result);
    }

    @GetMapping("/query-credit-card-bill")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> queryCreditCardBill(
            @RequestParam String bankCardId,
            @RequestParam String statementDate,
            @RequestParam int pageSize,
            @RequestParam int pageIndex) {
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;
        List<Map<String, Object>> result = incomeExpenseDetailService.queryCreditCardBill(accountGroupId, pageSize, pageIndex, bankCardId, DateHelper.parseFromLongDateTime(statementDate));

        return httpResponseHelper.getSuccessResponse(result);
    }

    @GetMapping("/query-credit-card-bill-amount")
    public ResponseEntity<ApiResponse<BigDecimal>> queryCreditCardBillAmount(@RequestParam String bankCardId, @RequestParam String statementDate) {
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;
        BigDecimal result = incomeExpenseDetailService.queryCreditCardBillAmount(accountGroupId, bankCardId, DateHelper.parseFromLongDateTime(statementDate));

        return httpResponseHelper.getSuccessResponse(result);
    }

    @GetMapping("/query-coordinates")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> queryCoordinates(@RequestParam String year) {
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;
        List<Map<String, Object>> result = incomeExpenseDetailService.queryCoordinates(accountGroupId, year);

        return httpResponseHelper.getSuccessResponse(result);
    }

    @PostMapping("/add")
    public ResponseEntity<ApiResponse<Object>> add(@Valid @RequestBody CreateIncomeExpenseDetailDto data) {
        MyClaims claims = requestIdentityExtractor.getClaims();
        incomeExpenseDetailService.add(claims.accountGroupId, claims.username, data);

        return httpResponseHelper.getSuccessResponse();
    }

    @PostMapping("/update")
    public ResponseEntity<ApiResponse<Object>> update(@Valid @RequestBody UpdateIncomeExpenseDetailDto data) {
        MyClaims claims = requestIdentityExtractor.getClaims();
        incomeExpenseDetailService.update(claims.accountGroupId, claims.username, data);

        return httpResponseHelper.getSuccessResponse();
    }

    @PostMapping("/delete")
    public ResponseEntity<ApiResponse<Object>> delete(@Valid @RequestBody IdentityDto data) {
        String id = data.getId();
        String accountGroupId = requestIdentityExtractor.getClaims().accountGroupId;
        incomeExpenseDetailService.delete(accountGroupId, List.of(id));

        return httpResponseHelper.getSuccessResponse();
    }
}
